https://mp.weixin.qq.com/s/p42enwBtwOJt8tkNZxhMOg


int shared_data = 0;

void func() {
    for (int i = 0; i < 100000; ++i) {
        shared_data++;
    }
}

int main() {
    std::thread t1(func);
    std::thread t2(func);
    t1.join();
    t2.join();
    std::cout << "shared_data = " << shared_data << std::endl;    
    return 0;
}
/*
上面的代码中，定义了一个名为shared_data的全局变量，并在两个线程中对其进行累加操作。在main函数中，创建了两个线程，并分别调用了func函数。
在func函数中，对shared_data变量进行了累加操作。

由于shared_data变量是全局变量，因此在两个线程中共享。对于这种共享的情况，需要使用互斥量等同步机制来确保多个线程之间对共享数据的访问是安全的。
如果不使用同步机制，就会出现数据竞争问题，导致得到错误的结果。
*/


#include <iostream>
#include <thread>
#include <mutex>

int shared_data = 0;
std::mutex mtx;

void func(int n) {
    for (int i = 0; i < 100000; ++i) {
        mtx.lock();
        shared_data++;        
        std::cout << "Thread " << n
                  << " increment shared_data to " << shared_data << std::endl;
        mtx.unlock();
    }
}

int main() {
    std::thread t1(func, 1);
    std::thread t2(func, 2);

    t1.join();
    t2.join();    

    std::cout << "Final shared_data = " << shared_data << std::endl;    
    return 0;
}
/*
shared_data变量由多个线程共享。
互斥量mtx确保多个线程不会同时修改shared_data，从而避免数据竞争。
mtx.lock()获取互斥量的所有权，保证当前线程独占访问shared_data。
mtx.unlock()释放互斥量，使其他线程可以继续访问shared_data。
这样就可以确保多个线程之间对shared_data变量的访问是安全的。
*/


//死锁的情况

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx1, mtx2;

void func1() {
    mtx2.lock();
    mtx1.lock();
    mtx1.unlock();
    mtx2.unlock();

}

void func2() {
    mtx1.lock();
    mtx2.lock();
    mtx2.unlock();
    mtx1.unlock();
}

int main() {
    std::thread t1(func1);
    std::thread t2(func2);
    t1.join();
    t2.join();
    return 0;
}

//解决办法：让两个线程按照相同的顺序获取互斥量的所有权。
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx1, mtx2;

void func1() {
    mtx2.lock();
    std::cout << "Thread 1 locked mutex 2" << std::endl;
    mtx1.lock();
    std::cout << "Thread 1 locked mutex 1" << std::endl;
    mtx1.unlock();
    std::cout << "Thread 1 unlocked mutex 1" << std::endl;
    mtx2.unlock();
    std::cout << "Thread 1 unlocked mutex 2" << std::endl;
}

void func2() {
    mtx2.lock();
    std::cout << "Thread 2 locked mutex 2" << std::endl;
    mtx1.lock();
    std::cout << "Thread 2 locked mutex 1" << std::endl;
    mtx1.unlock();
    std::cout << "Thread 2 unlocked mutex 1" << std::endl;
    mtx2.unlock();
    std::cout << "Thread 2 unlocked mutex 2" << std::endl;
}

int main() {
    std::thread t1(func1);
    std::thread t2(func2);
    t1.join();
    t2.join();
    return 0;
}